package mtest3.day2;

import mtest3.day1.IList;

//单链表
public class Linklist implements IList {
    //头指针 指向链表的第一个数据 如果没有数据 那么为null
    public Node head;
    //数据的长度
    private int len;


    public Linklist() {
        this.head = null;
        this.len = 0;
    }

    @Override
    public void add(Object e) {
        this.insert(this.len, e);
    }

    public void addFrist(Object e) {
        this.insert(0, e);
    }

    public void addLast(Object e) {
        this.insert(this.len, e);


    }


    @Override
    public void insert(int index, Object e) {
        // 判断index是否为空
        if (index == 0) {
//            // 1 创建要添加的节点元素
//            Node newnode = new Node(e);
//            // 2 让新节点的next 指向head
//            newnode.next = head;
//            // 3 让head 等于新的节点
//            head = newnode;
//            // 4 长度加一
//            len++;
            head = new Node(e, head);
//            len++;
        } else {
            // 1 定义一个节点等于head ，用来遍历查找后续的节点
            Node curNode = head;
            // 找到index之前的节点对象
            for (int i = 0; i < index - 1; i++) {
                curNode = curNode.next;
            }
            // 创建一个新的节点，让新节点指向curnode的下一个节点。
            // 让 curnode 指向新的节点
            curNode.next = new Node(e, curNode.next);
        }
        len++;

    }

    // 遍历
    public void show() {
        //  防止haed 本身的位置改变
        Node copy_head = head;
        while (copy_head != null) {
            System.out.println("数据------" + copy_head.data);
            // 指向下一个节点
            copy_head = copy_head.next;
        }
    }


    /**
     * 删除指定位置的元素
     *
     * @param index
     */
    @Override
    public void remove(int index) {
        if (index == 0) {
            // 找到head 的下一个next
            // 1 Node oldNode = head;
            head = head.next;
            // 2 return oldNode.data;
            // 返回数据就添加1，2
        } else {
            // 获取删除的index上一个节点
            Node preNode = getNode(index - 1);
            // 获取preNode 的下一个节点 ，也就是要删除的节点
            Node delNode = preNode.next;
            // 让preNode 指向delNoded的next
            preNode.next = delNode.next;
        }
        // 长度减一
        len--;

    }


    /**
     * 修改index位置的data为 e
     *
     * @param index 指定的节点
     * @param e     新的数据
     */
    @Override
    public void set(int index, Object e) {
        Node node = this.getNode(index);
        node.data = e;

    }


    /**
     * 获取index位置的节点 对象
     *
     * @param index
     * @return
     */
    public Node getNode(int index) {
        if (index < 0 || index >= len) {
            throw new RuntimeException("索引越界");
        }
        Node curNode = head;  //记录第一个节点
        for (int i = 0; i < index; i++) {
            curNode = curNode.next;
        }
        // curNode就是index位置的结点
        return curNode;
    }


    /**
     * 返回指定位置的data
     *
     * @param index 传入的指定位置
     * @return 指定位置的数据
     */
    @Override
    public Object get(int index) {
        Node node = getNode(index);
        return node.data;
    }

    //获取长度
    @Override
    public int size() {
        return len;
    }

    //是否为空
    @Override
    public boolean isEmpty() {
        return len == 0;
    }


    /**
     * 获取数据e 在链表中 第一次出现的位置
     *
     * @param e
     * @return 位置
     */
    @Override
    public int indexOf(Object e) {
        // 定义一个节点 ，等于head 用来next 遍历后续的节点
        Node curNode = head;
        int index = 0;
        while (curNode != null) {
            // 对比节点位置
            if (curNode.data.equals(e)) {
                // 返回索引位置
                return index;
            }
            // 指向下一个节点
            curNode = curNode.next;
            // 索引加一
            index++;
        }

        return -1;
    }

    // 是否包含该数据
    public boolean contains(Object e) {
        int index = this.indexOf(e);

        return index == -1 ? false : true;

    }

    @Override
    public String toString() {
        // 重写 list
        String result = "";
        Node copy_head = head;
        while (copy_head != null) {
            result += copy_head.data + "    ";
            copy_head = copy_head.next;

        }

        return result;
    }


}